﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Seasar.Framework.Aop.Interceptors;
using Seasar.Framework.Aop;
using System.Reflection;
using Shsc.Net.Common.Seasar.Extension.CustomAttribute;
using System.Web.Caching;

namespace Shsc.Net.Common.Seasar.Extension.Interceptor
{
    public class CacheInterceptor : AbstractInterceptor
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="invocation"></param>
        /// <returns></returns>
        public override object Invoke(global::Seasar.Framework.Aop.IMethodInvocation invocation)
        {
            object ret = null;
            CacheAttribute[] attributes = invocation.Method.GetCustomAttributes(typeof(CacheAttribute), true) as CacheAttribute[];
            CacheAttribute cacheAttribute = null;
            if (attributes.Length > 0)
            {
                cacheAttribute = attributes[0];
            }

            String key = invocation.Method.ReflectedType.Namespace
                + "." + invocation.Method.ReflectedType.Name
                + "." + invocation.Method.Name;
            if (cacheAttribute != null)
            {
                if (CacheAttribute.Cache.Get(key) == null)
                {
                    ret = base.Invoke(invocation);
                    cacheResult(cacheAttribute, key, ret);
                }
                else
                {
                    ret = CacheAttribute.Cache.Get(key);
                }
            }
            else
            {
                ret = base.Invoke(invocation);
            }
            return ret;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cacheAttribute"></param>
        /// <param name="key"></param>
        /// <param name="ret"></param>
        private void cacheResult(CacheAttribute cacheAttribute, string key, object ret)
        {
            switch (cacheAttribute.Expiration)
            {                
                case CacheRule.NoAbsoluteExpiration:
                    CacheAttribute.Cache.Insert(key, ret, null,
                        DateTime.Now.AddMinutes(cacheAttribute.ExpirationTime), TimeSpan.Zero);
                    break;
                case CacheRule.NoSlidingExpiration:
                    CacheAttribute.Cache.Insert(key, ret, null,
                        DateTime.MaxValue, TimeSpan.FromMinutes(cacheAttribute.ExpirationTime));
                    break;
                default:
                    CacheAttribute.Cache.Insert(key, ret);
                    break;
            }
        }


    }
}
